﻿using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Reflection;

namespace tjb.Utility.Reflection
{
    /// <summary>
    /// 
    /// </summary>
    public class ValueTextPair
    {
        /// <summary>
        /// 
        /// </summary>
        public int Value { get; set; }
        /// <summary>
        /// 
        /// </summary>
        public string Text { get; set; }
        /// <summary>
        /// 
        /// </summary>
        /// <param name="value"></param>
        /// <param name="text"></param>
        public ValueTextPair(int value, string text)
        {
            this.Value = value;
            this.Text = text;
        }
        /// <summary>
        /// 
        /// </summary>
        public ValueTextPair() { }
    }
    /// <summary>
    /// 
    /// </summary>
    public sealed class EnumHelper
    {
        private EnumHelper() { }
        private static Dictionary<Type, List<ValueTextPair>> enums = new Dictionary<Type, List<ValueTextPair>>();
        /// <summary>
        /// 获取一个枚举的列表
        /// </summary>
        /// <param name="enumType"></param>        
        /// <returns></returns>
        public static List<ValueTextPair> GetEnumList(Type enumType)
        {
            if (enums.ContainsKey(enumType))
                return enums[enumType];
            lock (enums)
            {
                if (enums.ContainsKey(enumType))
                    return enums[enumType];
                List<ValueTextPair> v = EnumToList(enumType);
                enums.Add(enumType, v);
                return v;
            }
        }
        /// <summary>
        /// 
        /// </summary>
        /// <typeparam name="T">必须是枚举Enum类型</typeparam>
        /// <returns></returns>
        public static List<ValueTextPair> GetEnumList<T>() where T : struct
        {
            return GetEnumList(typeof(T));
        }
        /// <summary>
        /// 
        /// </summary>
        /// <typeparam name="T"></typeparam>
        /// <param name="enumValue"></param>
        /// <returns></returns>
        public static string GetEnumList<T>(int enumValue) where T : struct
        {
            List<ValueTextPair> VTPairs = GetEnumList<T>();
            for (int i = VTPairs.Count - 1; i >= 0; i--)
                if (VTPairs[i].Value == enumValue)
                    return VTPairs[i].Text;
            return "";           
        }
        /// <summary>
        /// 
        /// </summary>
        /// <typeparam name="T"></typeparam>
        /// <param name="enumText"></param>
        /// <returns></returns>
        public static int GetEnumList<T>(string enumText) where T : struct
        {
            List<ValueTextPair> VTPairs = GetEnumList<T>();
            for (int i = VTPairs.Count - 1; i >= 0; i--)
                if (VTPairs[i].Text == enumText)
                    return VTPairs[i].Value;
            return 0;
        }


        #region Private Method
        private static List<ValueTextPair> EnumToList(Type enumType)
        {
            if (enumType == null || enumType.IsEnum == false)
            {
                throw new ArgumentException("参数 enumType 为空和或者不是Enum类型。");
            }
            Type typeDescription = typeof(DescriptionAttribute);
            List<ValueTextPair> list = new List<ValueTextPair>();
            FieldInfo[] fields = enumType.GetFields();
            string strText = string.Empty;
            int strValue;
            foreach (FieldInfo field in fields)
            {
                if (field.IsSpecialName) continue;
                strValue = (int)field.GetRawConstantValue();
                object[] arr = field.GetCustomAttributes(typeDescription, true);
                if (arr.Length > 0)
                {
                    strText = (arr[0] as DescriptionAttribute).Description;
                }
                else
                {
                    strText = field.Name;
                }

                list.Add(new ValueTextPair(strValue, strText));
            }
            return list;
        }



        #endregion
    }
}
